package cn.itsource.service.impl;

import cn.itsource.annotation.LogAOP;
import cn.itsource.domain.Article;
import cn.itsource.domain.IpAddress;
import cn.itsource.dto.ArticleDat;
import cn.itsource.dto.ArticleDto;
import cn.itsource.mapper.ArticleMapper;
import cn.itsource.mapper.IpAddressMapper;
import cn.itsource.query.Query;
import cn.itsource.service.ArticleService;
import cn.itsource.util.AjaxResult;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true)
public class ArticleServiceImpl implements ArticleService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private ArticleMapper articleMapper;

    @Autowired
    private IpAddressMapper ipAddressMapper;

    @Override
    public List<Article> findAll() {
        return articleMapper.findAll();
    }

    @Override
    public Article findOne(Long id) {
        Article article = articleMapper.findOne(id);
        article.setArticleReadCount(article.getArticleReadCount() + 1); //浏览当前网页。浏览量添加+1
        articleMapper.update(article); //浏览当前网页。浏览量添加+1
        return article;
    }

    @LogAOP
    @Transactional
    @Override
    public void add(Article article) {
        //把数据添加到sql数据库
        articleMapper.add(article);

        //把数据添加到mongo数据库
        mongoTemplate.save(article);

    }

    @LogAOP
    @Transactional
    @Override
    public void update(Article article) {
        article.setUpdateTime(new Date());
        articleMapper.update(article);

        //修改mongo数据库的数据、
        org.springframework.data.mongodb.core.query.Query query =
                new org.springframework.data.mongodb.core.query.Query(Criteria.where("id").is(article.getId()));

        Article mongoTemplateOne = mongoTemplate.findOne(query, Article.class);
        if (mongoTemplateOne != null) {
            article.set_id(mongoTemplateOne.get_id());
        }
        mongoTemplate.save(article);
    }

    @LogAOP
    @Transactional
    @Override
    public void delete(Long id) {
        articleMapper.delete(id);

        //通过id值从mongodb中删除
        //通过id值从mongodb中删除\
        org.springframework.data.mongodb.core.query.Query query =
                new org.springframework.data.mongodb.core.query.Query(Criteria.where("id").is(id));
        mongoTemplate.remove(query, Article.class);
    }

    //分页+模糊查询
    @Override
    public PageInfo<Article> pageQuery(Query query) {
        PageHelper.startPage(query.getCurrentPage(), query.getPageSize());
        List<Article> articles = articleMapper.pageQuery(query);
        return new PageInfo<>(articles);
    }

    //批量删除
    @Override

    public void patchdel(Long[] ids) {
        //articleMapper.patchdel(ids);
        for (Long id : ids) {
            delete(id);
        }
    }


    //获取文章类型
    @Override
    public List<ArticleDat> articleType() {
        return articleMapper.articleType();
    }

    //获取时间统计
    @Override
    public List<ArticleDat> timecount() {
        return articleMapper.timecount();
    }

    //获取相关文章内容
    @Override
    public List<Article> relatedArticles(Long id) {
        return articleMapper.relatedArticles(id);
    }

    //根据article_typeid 获取文章数据
    @Override
    public List<Article> articleList(Long articleTypeId) {
        return articleMapper.articleList(articleTypeId);
    }

    //获取按照年份分组
    @Override
    public List<Article> yearGrougBy() {
        return articleMapper.yearGrougBy();
    }

    //树状图
    @Override
    public List<Article> getNameandReadCount() {
        return articleMapper.getNameandReadCount();
    }

    //扇形
    @Override
    public List<ArticleDat> sector() {
        return articleMapper.sector();
    }

    //归档  Map<String, List<Article>>  循环里面循环
    @Override
    public List<ArticleDto> getBlogGdList() {

        List<Article> blogGdList = articleMapper.getBlogGdList();
        //根据年份进行分组：百度看例子
        //String保存的是年份，List<BlogArticle>保存当前年份的集合
        Map<String, List<Article>> resultMap = blogGdList.stream().collect(Collectors.groupingBy(Article::getYear));

        List<ArticleDto> result = new ArrayList<>();
        //遍历resultMap，封装结果进行返回
        for(String year : resultMap.keySet()){
            ArticleDto dto = new ArticleDto();
            dto.setYear(year);
            dto.setArticleList(resultMap.get(year));
            result.add(dto);
        }
        return result;
    }


    //前台系统点赞功能接口
    @Override
    public AjaxResult updateStar(Long id, HttpServletRequest request) {
        //通过文章id查询tb_ipaddress表ip地址
        List<String> address = ipAddressMapper.findByArticleId(id);
        //获取请求中的ip地址
        String ip = request.getRemoteAddr();
        if (address.contains(ip)){//包含函数(contains),数据库有ip地址 - 以前点赞了 - 再点就是取消点赞
            ipAddressMapper.delByIpAndArticleId(ip,id);
            articleMapper.decreStar(id);
            return AjaxResult.me().setMessage("cancel");
        }else {
            IpAddress ipAddress = new IpAddress();
            ipAddress.setAddress(ip);
            ipAddress.setArticleId(id);
            ipAddressMapper.add(ipAddress); //未点赞，添加数据给tb_ip_address表
            articleMapper.increStar(id); //未点赞，给tb_article表article_star_num字段+1
            return AjaxResult.me().setMessage("star");
        }
    }


    /**
     * 业务接口：前台点赞图片样式加载
     * @param id
     * @param request
     * @return
     */
    @Override
    public AjaxResult initIconClass(Long id, HttpServletRequest request) {
        List<String> ips = ipAddressMapper.findByArticleId(id);
        String ip = request.getRemoteAddr();
        if (ips.contains(ip)){//包含函数(contains),数据库有mac地址 - 以前点赞过 - 再点就是取消点赞
            return AjaxResult.me().setMessage("ok");
        }else {
            return AjaxResult.me().setMessage("no");
        }
    }

}
